
#pragma once
#include <string>
#include <iostream>
#include <functional>
#include "physics-enum.h"

#ifdef __EMSCRIPTEN__
#include "../../emsdk/upstream/emscripten/system/include/emscripten/bind.h"
#endif

class Vec3; // 向前引用
class Node;
class AABB;

/**
 * 碰撞体的基础变换属性直接继承节点的属性
 */
// 定义回调函数类型（参数：碰撞对象的ID）
typedef void (*CollisionCallback)(std::string);

class ColliderBase
{
private:
    // 基础属性的刷新索引
    int _ref;
    int _group;
    int _mask;

    PhysicsColliderType _type;
    PhysicsColliderGeometry _geometry;

    Node *_node;  //传入参数-无需释放
    AABB *_aabb;  //需要手动释放
    // 需要定义obb包围盒子

#ifdef __EMSCRIPTEN__
    emscripten::val m_jsCallback{emscripten::val::undefined()}; // wasm 使用时的回调绑定
#else
    CollisionCallback onCollisionCallback = nullptr; // C++ 本省 回调函数
#endif

protected:
public:
    ColliderBase(Node *node);
    ~ColliderBase();

    AABB *getAABB();
    Node *getNode();

    // 基础属性的刷新索引
    void addRef();
    void cleanRef();

    void setGroup(int group);
    int getGroup();

    void setMask(int mask);
    int getMask();

    void setGeometry(PhysicsColliderGeometry geometry);
    PhysicsColliderGeometry getGeometry();

    void update(float dt);

    void setType(PhysicsColliderType type);
    PhysicsColliderType getType();

#ifdef __EMSCRIPTEN__
    void setColliderCallback(emscripten::val jsCallback); // 添加碰撞回调
#else
    void setColliderCallback(CollisionCallback Callback); // 添加碰撞回调
#endif

    void clearColliderCallback(); // 清除回调注册

    float colliderTest(ColliderBase *collider); //  碰撞检测
    bool isOnCollider();
    void emitColliderCall(ColliderBase *collider);

    void _updateTransform();
    void destroy();
};
